home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / tls / tls060.ltr < prev    next >
Text File  |  1994-09-02  |  6KB  |  187 lines

  1. Subj: tls060 - C++ shared library building tools update
  2.  
  3.   How to build a shared library for SCO ODT using C++ source code
  4.   
  5.     This sounds easy, and can be if you follow the workarounds described
  6.   here.  Without the workarounds two problems and one annoyance exist.
  7.   
  8.   1) mkshlib will not allow uninitialized data to exist within a shared lib, 
  9.   including data that CC generates, such as the following decl, placed
  10.   into each object file CC generates:
  11.   
  12.   char __cfront_version_302_xxxxxxxx; 
  13.   
  14.   2) constructor functions will not be called within the body of C++ code 
  15.   that makes up the shared library.
  16.   
  17.   In addition, one other minor annoyance exists, there is no shared libC_s
  18.   to place in the specfile (#objects noload) to resolve the definitions for 
  19.   usefull things like new() and delete().  Most C++ code will use new() at 
  20.   some point, to find out if you use this routine look for an unresolved 
  21.   symbol "__nw__FUi" from mkshlib().
  22.   
  23.   
  24.   How to make it work:
  25.   
  26.   1) use the new version of mkshlib(CP) included in this TLS, this version 
  27.   allows uninitialized data to become initialized (to zero).
  28.   call mkshlib with the "-i" argument (new).
  29.   
  30.   $ mkshlib -i -s libstr.spec -t....
  31.   
  32.   2) this is a bit more work than #1.
  33.   Included in this TLS is an object "shlib_main.o", that must be 
  34.   added to the #objects list of your shared library. In addition the 
  35.   routine "shlib_main();" must be called by your library at 
  36.   some point prior to using any of the class member functions 
  37.   exported by your library.  Or to put it simply, your code 
  38.   must call shlib_main() first, and only once.  If your library
  39.   has an "initial" call, just add shlib_main() to the top of 
  40.   that routine.  
  41.   NOTE: calling shlib_main() from a constructor won't work, because
  42.   constructors won't get called until shlib_main() is called.
  43.   NOTE: shlib_main.o contains a data object "__head"
  44.   that must be hidden within the shared lib, use the following 
  45.   directive within the shared lib spec file: 
  46.   
  47.   #hide linker  
  48.   __head
  49.   
  50.   The function shlib_main(), starts at the head of a linked list 
  51.   of constructors and walks the list, calling each constructor
  52.   thus causing all classes to be properly initialized. 
  53.   
  54.   To cause the linked list to be built, you must run the version
  55.   of patch(CC) that is included in this TLS against the shared library
  56.   target file produced by mkshlib(CP).   Place the supplied version 
  57.   of patch in /usr/lib/CC, saving the original as a backup.
  58.   
  59.   The command line for patch will then look like this:
  60.   
  61.   $ /usr/lib/CC/patch libmyshlib_s 
  62.   
  63.   I put this in my makefile so that it is done right after mkhslib(CP)
  64.   An example will be included below.
  65.   
  66.   This version of patch must also exist in /usr/lib/CC when programs
  67.   that link with libmyshlib_s.a are built, the original version 
  68.   of patch will balk at the addresses within a coff file that contains
  69.   shared library addresses.
  70.   
  71.   Annoyance : 
  72.   your library may use new(), if so add the following objects 
  73.   to your #objects list in the mkshlib spec file.
  74.   
  75.    _new.o _delete.o _arr_map.o _vec.o _handler.o
  76.   
  77.   These will provide the definitions for new(), delete() and a few 
  78.   others that I found were necessary.  
  79.   Where do you get these objects ??, from /usr/lib/CC/libC.a, using ar, 
  80.   the following command should do it:
  81.   
  82.   $ ar x /usr/lib/CC/libC.a _new.o _delete.o _arr_map.o _vec.o _handler.o
  83.   
  84.   
  85.   Summary: 
  86.   1) get this TLS, unpack
  87.   2) backup and replace mkshlib(CP) (/usr/bin) and patch(CC) (/usr/lib/CC)
  88.   3) add shlib_main.o to the #objects list, and hide "__head", in the spec file.
  89.   4) guarantee that your lib will call shlib_main() first and once.
  90.   5) extract _new.o _delete.o, etc...  from libC.a, add them to #objects list
  91.   
  92.   Examples: 
  93.   
  94.     The following examples will create a shared lib, and link a try program
  95.     with it. the try program will extract a string from the lib. 
  96.   
  97.     Cut out these files, type "make", then "try" :
  98.   
  99.   $ make && try
  100.   hi
  101.   Hello World
  102.   
  103.     The string "Hello World" comes from within the shared lib, and is 
  104.     set up via a constructor, so we know that the library constructor 
  105.     was called.
  106.   
  107.   hess@sco.com
  108.   
  109.   --------------------- cut here for "makefile" -----------------
  110.   all: libstr_s.a try
  111.   try.o: try.C
  112.   CC $(CCFALGS) -c $? 
  113.   try: try.o libstr_s.a 
  114.   CC -o $@ try.o libstr_s.a -lc_s
  115.   
  116.   libstr_s.a : String.o shlib_main.o libstr.spec
  117.   mkshlib -qis libstr.spec -t /tmp/libstr_s -h $@
  118.   /usr/lib/CC/patch  /tmp/libstr_s
  119.   
  120.   String.o: String.C String.h
  121.   CC $(CCFALGS) -c String.C
  122.   
  123.   ---------------------- cut here for String.C ----------------
  124.   #include <string.h>
  125.   #include "String.h"
  126.   extern "C" void shlib_main(); 
  127.   String::String( char *s) 
  128.   { 
  129.   len = strlen(s); 
  130.   str = new char [ len + 1 ] ; 
  131.   strcpy ( str, s ); 
  132.   }
  133.   
  134.   String hello_wld("Hello World"); 
  135.   
  136.   char *String::sayhi() {
  137.   shlib_main(); // make sure we call this...
  138.   return  hello_wld.str;
  139.   }
  140.   
  141.   ---------------------- cut here for String.h ----------------
  142.   class String {
  143.   public:
  144.   String( int );
  145.   String( char* );
  146.   char *sayhi(); 
  147.   char *str;
  148.   private:
  149.   int len;
  150.   };
  151.   
  152.   ---------------------- cut here for libstr.spec ----------------
  153.   #address .text 0xB3400000
  154.   #address .data 0xB3800000
  155.   #target /tmp/libstr_s
  156.   #branch
  157.       __ct__6StringFPc1
  158.       sayhi__6StringFv    2
  159.       __sti__String_C_sayhi_ 3
  160.   
  161.   #objects
  162.   _new.o _delete.o _arr_map.o _vec.o _handler.o
  163.   shlib_main.o
  164.   String.o
  165.   
  166.   #objects noload 
  167.   -lc_s
  168.   
  169.   #hide linker 
  170.   __head
  171.   
  172.   
  173.   ---------------------- cut here for try.C ----------------
  174.   #include <stream.h>
  175.   #include "String.h"
  176.   main()
  177.   {
  178.   String common("not this string"); 
  179.           char *t = common.sayhi();
  180.           cout << "hi\n" ;
  181.           cout << t;
  182.           cout << "\n";
  183.   }
  184.   
  185.  
  186.  
  187.